// 实现 set 数据结构
package set

// Set 接口
type Set interface {

	// 添加元素到集合，返回元素是否添加成功
	Add(i interface{}) bool

	// 返回集合的元素数
	Size() int

	// 清空结合的所有元素，使集合为空
	Clear()

	// 判断给定元素是否都在集合内
	Contains(i ...interface{}) bool

	//ContainsOne 包含其中一个
	ContainsOne(i ...interface{}) bool

	// 移除集合中的一个元素
	Remove(i interface{})

	// 判断两个集合是否相等，如果它们有相同的 size 和 元素，就认为相等
	// 传入的集合类型需要和接收者相同，否则会 panic
	Equal(other Set) bool

	// 遍历每个元素，并且对每个元素执行传入的函数，如果函数返回 true， 则停止遍历
	Each(func(interface{}) bool)

	// 返回一个存储两个集合的差别的集合，在此集合里有，在另一个集合里没有的元素
	Difference(other Set) Set

	// 返回在两个集合里都存在的元素集合
	Intersect(other Set) Set

	// 返回两个集合中所有元素
	Union(other Set) Set

	// 以切片的形式返回集合的元素
	ToSlice() []interface{}
}

// NewSet 创建并返回一个集合
func NewSet(s ...interface{}) Set {
	set := newThreadUnsafeSet()
	for _, item := range s {
		set.Add(item)
	}
	return &set
}

// NewSetFormSlice 从一个切片来创建集合
func NewSetFormSlice(s []interface{}) Set {
	a := NewSet(s...)
	return a
}
